package com.android.nodejs.livejs.activities;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.Toast;

import com.android.nodejs.livejs.MyApplication;
import com.android.nodejs.livejs.R;
import com.android.nodejs.livejs.adapters.CropOptionAdapter;
import com.android.nodejs.livejs.constants.AddMessageConstants;
import com.android.nodejs.livejs.constants.DisplayConstants;
import com.android.nodejs.livejs.models.CropOption;
import com.android.nodejs.livejs.utils.CommonUtil;

public class ProfileActivity extends Activity {
	
	private EditText edtFullName, edtEmail, edtBirthDay;
	private RadioButton rbMale, rbFemale;
	private ImageView imageView;
	//private String selectedImagePath;
	private Uri mImageCaptureUri;
	@SuppressWarnings("unused")
	private Bitmap selectedAvatar;
	private float AVATAR_SIZE = 60;
	
	private int pYear;
	private int pMonth;
	private int pDay;
	
	private static final int CAPTURE_IMAGE = 100;
	private static final int SELECT_PICTURE = 101;
	private static final int CROP_PHOTO_CODE = 102;

    private ProgressDialog dialog;
    private ProgressDialog progressDialog;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_profile);
		init();
        //set DatePickerDialog
		setDateToDatePickerDialog(edtBirthDay.getText().toString().trim());
        // register broad cast
        IntentFilter filterMessageChat = new IntentFilter("UPDATE_PROFILE");
        getApplicationContext().registerReceiver(new MessageBroadCastReceiver(), filterMessageChat);
	}

	private void init() {
		dialog = new ProgressDialog(this);
		dialog.setMessage("Loading...Please wait!");
		dialog.setCancelable(false);
		
		edtFullName = (EditText) findViewById(R.id.edtFullName);
		edtEmail = (EditText) findViewById(R.id.edtEmail);
		edtBirthDay = (EditText) findViewById(R.id.edtBirthDay);
		rbMale = (RadioButton) findViewById(R.id.rbMale);
		rbFemale = (RadioButton) findViewById(R.id.rbFemale);
		imageView = (ImageView) findViewById(R.id.imgProfilePicture);
		
		//set information to each field
		edtFullName.setText(MyApplication.USER_CURRENT.getFullName());
		edtEmail.setText(MyApplication.USER_CURRENT.getEmail());
		edtBirthDay.setText(MyApplication.USER_CURRENT.getBirthday());
		if(MyApplication.USER_CURRENT.getGender() == 1) {
			rbMale.setChecked(true);
		} else {
			rbFemale.setChecked(true);
		}
	}
	
	public void onClickBack(View v) {
		setResult(RESULT_CANCELED);
		finish();
	}
	
	public void onClickSave(View v) {
		if(isNullAllFields()) {
			Toast.makeText(getApplicationContext(), "Please fill all fields!", Toast.LENGTH_LONG).show();
		} else if(!checkValidateEmail(edtEmail.getText().toString())) {
			Toast.makeText(getApplicationContext(), "Wrong email address format!", Toast.LENGTH_LONG).show();
		} else if(MyApplication.USER_CURRENT.getFullName().equals(edtFullName.getText().toString().trim())
		        && MyApplication.USER_CURRENT.getBirthday().equals(edtBirthDay.getText().toString().trim())
		        && MyApplication.USER_CURRENT.getGender() == (rbMale.isChecked() ? 1 : 0)) {
            Toast.makeText(getApplicationContext(), "Your profile does not change anything!", Toast.LENGTH_LONG).show();
        } else {
		    progressDialog = ProgressDialog.show(ProfileActivity.this, "", "Updating your profile...");
            new Thread(new Runnable() {
                public void run() {
                    try {
                        if (MyApplication.OS_CURRENT == null) {
                            if (progressDialog.isShowing()) {
                                progressDialog.dismiss();
                            }
                            return;
                        }
                        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(MyApplication.OS_CURRENT));
                        w.write(AddMessageConstants.UPDATE_PROFILE);
                        JSONObject jsonProfile = new JSONObject();
                        jsonProfile.put("full_name", edtFullName.getText().toString().trim());
                        jsonProfile.put("email", edtEmail.getText().toString().trim());
                        jsonProfile.put("birthday", edtBirthDay.getText().toString().trim());
                        jsonProfile.put("gender", rbMale.isChecked() ? 1 : 0);
                        w.write(jsonProfile.toString());
                        w.flush();

                        if (progressDialog.isShowing()) {
                            progressDialog.dismiss();
                        }
                    } catch (SocketTimeoutException e) {
                        if (progressDialog.isShowing()) {
                            progressDialog.dismiss();
                        }
                        Message msg = toastHandler.obtainMessage(2);
                        toastHandler.sendMessage(msg);
                        return;
                    } catch (UnknownHostException e) {
                        Log.d("UnknownHostException", e.getClass().getSimpleName() + ": " + e.getMessage());
                        e.printStackTrace();
                    } catch (IOException e) {
                        Log.d("IOException", e.getClass().getSimpleName() + ": " + e.getMessage());
                        e.printStackTrace();
                    } catch (Exception e) {
                        Log.d("Exception", e.getClass().getSimpleName() + ": " + e.getMessage());
                        e.printStackTrace();
                    }
                }
            }).start();
		}
	}
	
	@SuppressWarnings("deprecation")
	public void onClickDatePicker(View v) {
		showDialog(0);
	}
	
	/**
	 * Take photo
	 * @param v
	 */
	public void onClickTakeAPhoto(View v) {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		mImageCaptureUri = Uri.fromFile(new File(Environment
				.getExternalStorageDirectory(), "tmp_avatar_"
				+ String.valueOf(System.currentTimeMillis()) + ".jpg"));

		takePictureIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
				mImageCaptureUri);
		takePictureIntent.putExtra("return-data", true);
		startActivityForResult(takePictureIntent, CAPTURE_IMAGE);
	}

	/**
	 * choose image from gallery
	 * @param v
	 */
	public void onClickChooseFromGallery(View v) {
		Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
			case CAPTURE_IMAGE:
				doCrop();
				break;
			case SELECT_PICTURE:
				mImageCaptureUri = data.getData();
				doCrop();
				break;
			case CROP_PHOTO_CODE:
				Bundle extras = data.getExtras();
				if (extras != null) {
					Bitmap bitmap = extras.getParcelable("data");
					imageView.setImageBitmap(bitmap);
					selectedAvatar = CommonUtil.getResizedBitmap(bitmap,
							(int) AVATAR_SIZE, (int) AVATAR_SIZE);
				}
				File f = new File(mImageCaptureUri.getPath());
				Log.d("PATH", mImageCaptureUri.getPath());
				if (f.exists()) {
					f.delete();
				}
				break;
			}
		}
	}
	
	public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        @SuppressWarnings("deprecation")
		Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
	

	/**
	 * check null all fields
	 * 
	 * @return true if have a field is null, invert return false if haven't
	 */
	public boolean isNullAllFields() {
		if ("".equals(edtFullName.getText().toString().trim())
				|| "".equals(edtEmail.getText().toString().trim())
				|| "".equals(edtBirthDay.getText().toString().trim())
				|| (!rbMale.isChecked() && !rbFemale.isChecked())) {
			return true;
		}
		return false;
	}

	/**
	 * check validate email address format
	 * @param email_address
	 * @return true if valid, false if invalid
	 */
	public boolean checkValidateEmail(String email_address){
		return email_address.matches("^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
		+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");
	}
	
	
	private void doCrop() {
		final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setType("image/*");
		List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, 0);
		int size = list.size();
		if (size == 0) {
			CommonUtil.toastNotify(this, getString(R.string.crop_image_no_app));
			return;
		} else {
			intent.setData(mImageCaptureUri);
			intent.putExtra("outputX", 200);
			intent.putExtra("outputY", 200);
			intent.putExtra("aspectX", 1);
			intent.putExtra("aspectY", 1);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);
			if (size == 1) {
				Intent i = new Intent(intent);
				ResolveInfo res = list.get(0);
				i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
				startActivityForResult(i, CROP_PHOTO_CODE);
			} else {
				for (ResolveInfo res : list) {
					final CropOption cropoption = new CropOption();
					cropoption.title = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
					cropoption.icon = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
					cropoption.appIntent = new Intent(intent);
					cropoption.appIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
					cropOptions.add(cropoption);
				}
				CropOptionAdapter adapter = new CropOptionAdapter(this,
						R.layout.cropoption_item, cropOptions);
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle(getString(R.string.crop_image_dialog_title));
				builder.setAdapter(adapter,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int item) {
								startActivityForResult(cropOptions.get(item).appIntent, CROP_PHOTO_CODE);
							}
						});

				builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
					public void onCancel(DialogInterface dialog) {
						if (mImageCaptureUri != null) {
							getContentResolver().delete(mImageCaptureUri, null, null);
							mImageCaptureUri = null;
						}
					}
				});
				AlertDialog alert = builder.create();
				alert.show();
			}
		}
	}
	
	// =======date picker============
	/** Callback received when the user "picks" a date in the dialog */
	private DatePickerDialog.OnDateSetListener pDateSetListener = new DatePickerDialog.OnDateSetListener() {
		public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
			pYear = year;
			pMonth = monthOfYear;
			pDay = dayOfMonth;
			updateDisplay();
		}
	};

	/** Updates the date in the TextView */
	private void updateDisplay() {
		edtBirthDay.setText(new StringBuilder()
				// Month is 0 based so add 1
				.append(pYear)
				.append("/")
				.append(pMonth + 1)
				.append("/")
				.append(pDay));
	}

	/** Create a new dialog for date picker */
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case 0:
			return new DatePickerDialog(this, pDateSetListener, pYear, pMonth, pDay);
		}
		return null;
	}
	
	/**
	 * set date to datetimepicker
	 * 
	 * @param dateString
	 */
	private void setDateToDatePickerDialog(String dateString) {
		DateFormat parseFormat = new SimpleDateFormat("yyyy/MM/dd");
	    DateFormat formattingFormat = new SimpleDateFormat("dd/MM/yyyy");
	    String date;
		try {
			date = formattingFormat.format(parseFormat.parse(dateString));
			pDay = Integer.parseInt(date.substring(0, 2));
			pMonth = Integer.parseInt(date.substring(3, 5))-1;
			pYear = Integer.parseInt(date.substring(6, 10));
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	
	/** Show Toast message */
    private Handler toastHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                Toast.makeText(getApplicationContext(), DisplayConstants.DIS_UPDATE_PROFILE_FAIL, Toast.LENGTH_LONG).show();
            } else if (msg.what == 1) {
                Toast.makeText(getApplicationContext(), DisplayConstants.DIS_UPDATED_PROFILE_SUCCESS, Toast.LENGTH_LONG).show();
                // set info to USER_CURRENT
                MyApplication.USER_CURRENT.setFullName(edtFullName.getText().toString().trim());
                MyApplication.USER_CURRENT.setBirthday(edtBirthDay.getText().toString().trim());
                MyApplication.USER_CURRENT.setGender(rbMale.isChecked() ? 1 : 0);
                // finish ProfileActivity
                finish();
            } else if (msg.what == 2) {
                CommonUtil.dialogNotify(ProfileActivity.this, DisplayConstants.DIS_CONNECT_SERVER_FAIL);
            }
        }
    };
    
    /**
     * receiver message broadcast
     * 
     * @author vuvt
     *
     */
    private class MessageBroadCastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if("UPDATE_PROFILE".equals(intent.getAction())) {
                int num = Integer.parseInt(intent.getStringExtra("msg"));
                Message msg = toastHandler.obtainMessage(num);
                toastHandler.sendMessage(msg);
            }
        }
    }
}
